#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"

#define NO_OF_SAMPLES 10
#define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate
#define FBATT_ADC_CHANNLE ADC_CHANNEL_3

static esp_adc_cal_characteristics_t *adc_chars;

const uint16_t charge_tbl[] =
    {
        4009,
        3985,
        3964,
        3952,
        3941,
        3926,
        3916,
        3901,
        3890,
        3876,
        3866,
        3857,
        3843,
        3833,
        3819,
        3810,
        3796,
        3786,
        3778,
        3763,
        3754,
        3741,
        3731,
        3718,
        3710,
        3701,
        3688,
        3678,
        3665,
        3657,
        3644,
        3635,
        3626,
        3612,
        3604,
        3592,
        3584,
        3571,
        3563,
        3556,
        3544,
        3536,
        3526,
        3518,
        3509,
        3503,
        3497,
        3488,
        3483,
        3474,
        3469,
        3462,
        3458,
        3453,
        3447,
        3443,
        3437,
        3433,
        3427,
        3424,
        3420,
        3414,
        3411,
        3404,
        3401,
        3395,
        3391,
        3387,
        3382,
        3378,
        3371,
        3368,
        3361,
        3358,
        3353,
        3346,
        3342,
        3334,
        3330,
        3322,
        3318,
        3312,
        3305,
        3300,
        3291,
        3285,
        3276,
        3269,
        3261,
        3249,
        3240,
        3225,
        3214,
        3196,
        3181,
        3163,
        3131,
        3097,
        3014,
        2914,
        2752};

uint8_t charge_status; //0 discharge 1 charge

uint16_t fbatt_get_voltage(void)
{
    adc1_config_width(ADC_WIDTH_BIT_13);
    adc1_config_channel_atten(FBATT_ADC_CHANNLE, ADC_ATTEN_DB_2_5);
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_2_5, ADC_WIDTH_BIT_13, DEFAULT_VREF, adc_chars);
    //print_char_val_type(val_type);
    uint32_t adc_reading = 0;
    //Multisampling
    for (int i = 0; i < NO_OF_SAMPLES; i++)
    {
        adc_reading += adc1_get_raw((adc1_channel_t)FBATT_ADC_CHANNLE);
    }
    adc_reading /= NO_OF_SAMPLES;
    //Convert adc_reading to voltage in mV
    uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
    voltage = voltage * 43 / 10;
    printf("Voltage: %dmV\n", voltage);
    return voltage;
}

uint8_t fbatt_get_percent(void)
{
    uint8_t i;
    uint16_t tmp_voltage = fbatt_get_voltage();
    for (i = 0; i <= 100; i++)
    {
        if (tmp_voltage >= charge_tbl[i])
        {
            return 100 - i;
        }
    }
    return 0;
}
